Feature #108
closedProvision SSM-Only AWS Infrastructure for BEL Production Instance
Description
Provision SSM-Only AWS Infrastructure for BEL Production Instance¶
Build the complete AWS footprint for customer BEL (Belimo Automation India Pvt. Ltd.) following the Canofy production SOP: EC2 managed only through SSM, encrypted storage, S3 bucket, backups, OCR bucket access and DNS.
1. Executive Summary¶
This story covers every AWS resource for the new BEL production instance in ap-south-1. The SOP was adapted for an SSM-only model (no SSH, no key pair, no port 22) and for end-to-end ownership by Canofy (no Promantia hand-off). All core resources are in place and verified by command output or console screenshots. A few hardening items were knowingly deferred; they are listed in Known Limitations.
2. Business / User Requirement¶
| # | Requirement | Description | Status |
|---|---|---|---|
| 1 | Follow Canofy production SOP | EC2, Elastic IP, S3, IAM, lifecycle, DNS as per the existing SOP | Implemented |
| 2 | SSM only | No SSH access going forward; all administration via Session Manager | Implemented |
| 3 | No Promantia dependency | Canofy performs IAM and all other steps | Implemented |
| 4 | Encrypted EBS | ISO audit finding: volumes must be encrypted | Implemented |
| 5 | Customer naming convention | Customer code BEL used in names and tags |
Implemented |
| 6 | Screenshots for SOP | Capture key screens for the standard SOP | Partial (several SS-xx captured; some pending) |
3. Problem Statement¶
The existing SOP assumed SSH (PEM key, port 22) and a Promantia hand-off for IAM and bench setup. Canofy now needs a repeatable, auditable, SSM-only process it can run itself. Several SOP details also needed correcting along the way: upper-case bucket names, which S3 rejects; the backup-policy tag model; and OCR policy coverage.
4. Objectives¶
- Launch a production EC2 instance reachable only through SSM.
- Provide a customer-dedicated, encrypted S3 bucket accessible by the instance role, without access keys.
- Grant the shared OCR server access to the new bucket.
- Enrol the instance in automated snapshot backups.
- Publish
bel.canofy.techthrough GoDaddy DNS.
5. Scope¶
In Scope¶
IAM policy and role, security group, EC2, EBS, Elastic IP, S3 bucket (versioning, encryption, TLS-only policy, lifecycle), the OCR IAM policy update, DLM backup enrolment, and the GoDaddy A record.
Out of Scope¶
Frappe and OS installation (STORY-2), golden AMI (STORY-3), application configuration (STORY-4/5/6).
Future Scope¶
Session Manager logging, IMDSv2 enforcement, a 40 GB disk, and an S3 VPC endpoint or VPC-restricted bucket policy (an existing research item for Murli).
7. Implemented Solution¶
| Resource | Final configuration | Evidence |
|---|---|---|
| EC2 instance |
i-0be6b206aecd2807e, Name #LIVE Production Belimo Automation India, t3a.medium, Ubuntu 22.04.5 LTS, no key pair, termination and stop protection |
Console screenshot; lsb_release output |
| IAM role |
EC2-Canofy-BEL-SSM-Prod = SSM core permissions + S3-BEL
|
aws sts get-caller-identity shows the assumed role |
IAM policy S3-BEL
|
ListBucket/GetBucketLocation on bucket; Get/Put/DeleteObject on bucket/*
|
S3 upload/list/delete test passed |
| Security group | Inbound 80/443 only, no port 22; outbound all | User-confirmed ("All set properly"); screenshot not provided |
| EBS root volume |
vol-0cc1d95a7394d274a, 20 GiB gp3, 3000 IOPS / 125 MB/s, Encrypted (aws/ebs), Name #LIVE Production Belimo Automation India [BEL]
|
Volume details screenshot |
| Elastic IP |
3.6.128.118 associated; auto-assigned IP removed |
Console screenshot; checkip returns the EIP |
| S3 bucket |
bel.canofy.tech, ap-south-1, versioning on, SSE-S3 + Bucket Key, SSE-C blocked, public access blocked, TLS-only bucket policy |
Properties screenshot (Permissions tab screenshot pending) |
| S3 lifecycle |
BEL-cleanup-old-versions: delete noncurrent after 90 days, expired delete markers, incomplete multipart uploads after 7 days |
User-confirmed |
| S3 lifecycle (backups) |
BEL-expire-db-backups: prefix _backups/, expire after 30 days |
Instructions given; not confirmed |
| OCR policy |
OCR-production-S3: bel.canofy.tech and /* added to both the Allow and the Deny/NotResource statements |
Editor screenshot + user confirmation of the CloudShell count |
| Snapshots (DLM) | Volume added to existing 60_day_production_instances (target type VOLUME, key Name); default 14-day policy also active |
Policy screenshot + user confirmation |
| DNS | GoDaddy A record bel → 3.6.128.118
|
Proven by successful Let's Encrypt issuance (STORY-2) |
8. Architecture¶
flowchart LR
Admin[Canofy operator] -->|Session Manager| SSM[AWS Systems Manager]
SSM --> EC2[EC2 BEL t3a.medium<br/>Ubuntu 22.04]
Internet[Users] -->|HTTPS 443 / HTTP 80| EIP[EIP 3.6.128.118]
EIP --> EC2
DNS[GoDaddy bel.canofy.tech] -.A record.-> EIP
EC2 -->|Instance role EC2-Canofy-BEL-SSM-Prod| S3[(S3 bel.canofy.tech)]
OCR[OCR server] -->|OCR-production-S3 policy| S3
DLM[Data Lifecycle Manager] -->|daily snapshots| EBS[(EBS 20 GiB encrypted)]
EC2 --- EBS
9. End-to-End Workflow¶
- Create the
S3-BELpolicy and attach it to the role used at launch (EC2-Canofy-BEL-SSM-Prod). - Check the security group (80/443, no 22).
- Launch EC2 without a key pair; verify the instance details.
- Verify the encrypted EBS volume, then name and tag it.
- Allocate and associate the Elastic IP.
- Verify SSM connectivity (
whoami=ssm-user, agent active, outbound IP = EIP). - Create the S3 bucket, its policy and lifecycle; test access from the instance role.
- Add the bucket to
OCR-production-S3(both statements). - Enrol the volume in the DLM policy.
- Add the GoDaddy A record.
10. Detailed Technical Logic¶
10.1 OCR policy Deny/NotResource pattern¶
Purpose: limit the OCR role to customer buckets only.
Processing: the Allow statement lists bucket ARNs, and a Deny on s3:* with NotResource blocks everything not listed.
Important rule: every new customer bucket must be added to both statements, or OCR is denied access. The first save attempt was lost, and the BEL lines were added again and saved later.
10.2 DLM enrolment via the Name tag¶
Purpose: reuse the existing combined production backup policy.
Processing: the policy targets VOLUME resources with key Name, value #LIVE Production <Client> [CODE]. The BEL volume Name tag was set to that pattern, and the policy entry Name | #LIVE Production Belimo Automation India [BEL] was added. An initially mistyped key (BEL) and a mixed-up Customer tag value were corrected.
14. Edge Cases & Error Handling¶
| Scenario | Handling | Status |
|---|---|---|
Upper-case SOP bucket format Canofy-xyz
|
S3 requires lower case; documented as a SOP correction | Resolved |
Dotted bucket name bel.canofy.tech (user choice) |
Risk explained (virtual-host TLS); CLI and boto3 work; SLC (slc.canofy.tech) is a working precedent |
Accepted |
OCR-production-S3 save not persisted |
Re-edited; verified with JSON view / CloudShell count | Resolved |
Pre-existing mil.canofy.tech/ trailing-slash typo (lines 22/42) |
Left untouched, to avoid changing another customer in a BEL change | Logged for separate fix |
| Marketplace vs public Ubuntu AMI | Public Canonical AMI recommended (no product code in a golden AMI) | Which one was used is not confirmed |
15. Configuration / Dependencies¶
| Setting | Value |
|---|---|
| Region | ap-south-1 |
| VPC |
vpc-cadaeca2 (172.31.0.0/16 default VPC) |
| Private IP | 172.31.10.27 |
| Elastic IP | 3.6.128.118 |
| Bucket folder used by the app | BEL |
16. Testing & Verification¶
| Test | Expected | Actual | Status |
|---|---|---|---|
| SSM session |
ssm-user, Ubuntu 22.04, agent active |
As expected | PASS |
| Outbound IP | 3.6.128.118 |
3.6.128.118 |
PASS |
| Role identity | assumed-role EC2-Canofy-BEL-SSM-Prod
|
As expected | PASS |
| S3 put/list/delete with role | No Access Denied | upload / list / delete succeeded | PASS |
| EBS encryption | Encrypted, aws/ebs | Encrypted, aws/ebs | PASS |
| DNS resolution |
bel.canofy.tech → EIP |
Let's Encrypt validation succeeded | PASS (indirect) |
| OCR server S3 access test | upload/list/delete from OCR | User reported "All done"; output not shared | NOT VERIFIED |
| First DLM snapshot | Snapshot next day | Not checked in conversation | NOT VERIFIED |
17. Current Status¶
| Area | Status | Notes |
|---|---|---|
| Implementation | Complete | All core resources created |
| Testing | Partial | Instance/S3 verified; OCR-side S3 test and first snapshot not evidenced |
| Documentation | Partial | Some SOP screenshots pending (e.g. SS-12, SS-26b) |
18. Known Limitations¶
- t3a.medium instead of t3a.large: accepted by the user. Impact: 3.8 GB RAM; mitigated with 4 GB swap and 3 gunicorn workers.
- IMDSv2 optional: accepted for now. Impact: weaker protection of role credentials against SSRF. Resolution: set "V2 only" before the ISO audit (no downtime).
-
20 GB root disk: user chose to expand later; about 48% used after the bench install. Resolution: online resize to 40 GB (
growpart+resize2fs). - Session Manager logging not enabled: deferred; there is no command audit trail yet.
-
Bucket tag key
customer(lower case): fix toCustomerrequested; not confirmed. - App/OCR S3 client with dotted bucket names: works today (SLC precedent); path-style addressing is the fallback if TLS errors appear.
19. Decisions & Important Design Notes¶
| Decision | Reason |
|---|---|
| No key pair, no port 22 | SSM-only access model requested by the user |
| One role with SSM + S3 policies | An EC2 instance can hold only one instance profile |
Bucket bel.canofy.tech (not canofy-bel) |
User decision; matches the SLC naming precedent |
Reuse the 60-day DLM policy with Name tags |
Matches the existing per-customer pattern |
| Leave the MIL policy typo alone | Avoid mixing changes to another live customer |
20. Future Enhancements / Next Steps¶
- Enforce IMDSv2 (hop limit 1–2).
- Expand EBS to 40 GB before go-live.
- Enable Session Manager logging to CloudWatch (needs a CloudWatch Logs permission on the role).
- Fix the
customer→Customerbucket tag; confirm the_backups/lifecycle rule. - Verify the first DLM snapshot of the BEL volume.
- Fix the
mil.canofy.tech/typo inOCR-production-S3as a separate change.
21. Final Outcome¶
The BEL AWS footprint is live and SSM-managed. The instance reaches S3 through its role without keys, and DNS points to the Elastic IP. The remaining work is hardening and verification, not missing infrastructure.
Story Key:
STORY-1
Generated From: Claude conversation (BEL production onboarding)
Pushed to Redmine on 01 Oct 2026, 10:33 from README.md (README created 01 Oct 2026, 10:32).
Files
RA Updated by Redmine Admin 21 days ago
- Due date set to 09/30/2026
- Status changed from New to Closed
- Start date changed from 10/01/2026 to 09/28/2026
- Estimated time set to 6:00 h