mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-09-30 10:43:13 +00:00
feat(terraform): complete dev environment adoption
This commit is contained in:
parent
e1e547f7d0
commit
e25a936da4
4 changed files with 88 additions and 11 deletions
|
|
@ -187,6 +187,32 @@ npm run deploy # deploy the stack (requires AWS)
|
|||
|
||||
All commands run from `infra/cdk/`.
|
||||
|
||||
## Terraform ownership transfer
|
||||
|
||||
`ManageGithubDeployRole` deliberately has no default. Every CDK deployment must
|
||||
state the intended ownership phase:
|
||||
|
||||
```bash
|
||||
# Before the controlled Terraform apply: install Retain on the role and policy.
|
||||
npx cdk deploy shoc-backend-deploy-dev \
|
||||
--parameters shoc-backend-deploy-dev:ManageGithubDeployRole=true
|
||||
|
||||
# After Terraform succeeds and live verification passes: relinquish ownership.
|
||||
npx cdk deploy shoc-backend-deploy-dev \
|
||||
--parameters shoc-backend-deploy-dev:ManageGithubDeployRole=false
|
||||
```
|
||||
|
||||
Both deployments must use the same reviewed SHA. The first keeps the role and
|
||||
generated inline policy under CloudFormation while adding retention metadata.
|
||||
The second removes both resources from CloudFormation ownership while retaining
|
||||
them live for Terraform. After the second deployment succeeds,
|
||||
`ManageGithubDeployRole=true` must never be used again.
|
||||
|
||||
Omitting the parameter fails closed before deployment. If the `true` deployment
|
||||
rolls back, inspect the stack resources and live role/policy before retrying;
|
||||
retained resources can outlive a failed update and must not be cleaned up
|
||||
automatically.
|
||||
|
||||
## CI integration
|
||||
|
||||
`npm run synth` is the deterministic local/CI validation. After synth, inspect
|
||||
|
|
@ -194,6 +220,9 @@ All commands run from `infra/cdk/`.
|
|||
`AWS::IAM::Role`:
|
||||
|
||||
- Trust policy `StringEquals` matches the exact audience and subject above.
|
||||
- The role, generated `AWS::IAM::Policy`, and role ARN output share the
|
||||
`ManageGithubDeployRoleCondition`; both resources use `DeletionPolicy` and
|
||||
`UpdateReplacePolicy` set to `Retain`.
|
||||
- The inline policy contains no `Resource: "*"` mutation action and no service
|
||||
outside `elasticbeanstalk` / `s3` / `cloudformation` / `ec2` /
|
||||
`elasticloadbalancing` / `autoscaling`. CloudFormation discovery and
|
||||
|
|
|
|||
|
|
@ -14,6 +14,27 @@ export class DeployDevStack extends cdk.Stack {
|
|||
constructor(scope: Construct, id: string, props: cdk.StackProps = {}) {
|
||||
super(scope, id, props);
|
||||
|
||||
const manageGithubDeployRole = new cdk.CfnParameter(
|
||||
this,
|
||||
'ManageGithubDeployRole',
|
||||
{
|
||||
type: 'String',
|
||||
allowedValues: ['true', 'false'],
|
||||
description:
|
||||
'Set true only before Terraform adoption. After ownership transfer, always reuse false.',
|
||||
},
|
||||
);
|
||||
const manageGithubDeployRoleCondition = new cdk.CfnCondition(
|
||||
this,
|
||||
'ManageGithubDeployRoleCondition',
|
||||
{
|
||||
expression: cdk.Fn.conditionEquals(
|
||||
manageGithubDeployRole.valueAsString,
|
||||
'true',
|
||||
),
|
||||
},
|
||||
);
|
||||
|
||||
const applicationArn = `arn:aws:elasticbeanstalk:${REGION}:${ACCOUNT_ID}:application/${APPLICATION_NAME}`;
|
||||
const environmentArn = `arn:aws:elasticbeanstalk:${REGION}:${ACCOUNT_ID}:environment/${APPLICATION_NAME}/${ENVIRONMENT_NAME}`;
|
||||
const oidcProviderArn = `arn:aws:iam::${ACCOUNT_ID}:oidc-provider/token.actions.githubusercontent.com`;
|
||||
|
|
@ -38,6 +59,7 @@ export class DeployDevStack extends cdk.Stack {
|
|||
const cfnRole = deployRole.node.defaultChild as iam.CfnRole;
|
||||
cfnRole.cfnOptions.deletionPolicy = cdk.CfnDeletionPolicy.RETAIN;
|
||||
cfnRole.cfnOptions.updateReplacePolicy = cdk.CfnDeletionPolicy.RETAIN;
|
||||
cfnRole.cfnOptions.condition = manageGithubDeployRoleCondition;
|
||||
|
||||
deployRole.addToPolicy(
|
||||
new iam.PolicyStatement({
|
||||
|
|
@ -134,10 +156,25 @@ export class DeployDevStack extends cdk.Stack {
|
|||
}),
|
||||
);
|
||||
|
||||
new cdk.CfnOutput(this, 'GithubDeployRoleArn', {
|
||||
value: deployRole.roleArn,
|
||||
description: 'ARN of the GitHub OIDC deploy role for shoc-backend dev.',
|
||||
exportName: 'shoc-backend-deploy-dev-role-arn',
|
||||
});
|
||||
const defaultPolicy = deployRole.node.findChild(
|
||||
'DefaultPolicy',
|
||||
) as iam.Policy;
|
||||
defaultPolicy.applyRemovalPolicy(cdk.RemovalPolicy.RETAIN);
|
||||
const cfnDefaultPolicy = defaultPolicy.node.defaultChild as iam.CfnPolicy;
|
||||
cfnDefaultPolicy.cfnOptions.deletionPolicy = cdk.CfnDeletionPolicy.RETAIN;
|
||||
cfnDefaultPolicy.cfnOptions.updateReplacePolicy =
|
||||
cdk.CfnDeletionPolicy.RETAIN;
|
||||
cfnDefaultPolicy.cfnOptions.condition = manageGithubDeployRoleCondition;
|
||||
|
||||
const githubDeployRoleArn = new cdk.CfnOutput(
|
||||
this,
|
||||
'GithubDeployRoleArn',
|
||||
{
|
||||
value: deployRole.roleArn,
|
||||
description: 'ARN of the GitHub OIDC deploy role for shoc-backend dev.',
|
||||
exportName: 'shoc-backend-deploy-dev-role-arn',
|
||||
},
|
||||
);
|
||||
githubDeployRoleArn.condition = manageGithubDeployRoleCondition;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,8 +94,9 @@ tf-poc rehearsal has completed both phases and therefore pins
|
|||
creates, deletes, replacements, and managed resource types outside the
|
||||
approved environment-owned boundary.
|
||||
4. Apply the no-op import only after review.
|
||||
5. Change the environment root to `adoption_complete=true` in a reviewed code
|
||||
change, then review the controlled in-place role and policy update:
|
||||
5. Change the environment root to `adoption_complete=true` and
|
||||
`manage_eb_settings=true` in a reviewed code change, then review the
|
||||
controlled in-place role, policy, secret, and Elastic Beanstalk update:
|
||||
|
||||
```bash
|
||||
# Dev example. Omit any address that is not updating.
|
||||
|
|
@ -104,11 +105,21 @@ tf-poc rehearsal has completed both phases and therefore pins
|
|||
--allow-update-address module.environment.aws_iam_role.runtime \
|
||||
--allow-update-address module.environment.aws_iam_role.github_deploy \
|
||||
--allow-update-address module.environment.aws_iam_role_policy.github_deploy \
|
||||
--allow-update-address module.environment.aws_secretsmanager_secret.app_config
|
||||
--allow-update-address module.environment.aws_secretsmanager_secret.app_config \
|
||||
--allow-update-address module.environment.aws_elastic_beanstalk_environment.this
|
||||
```
|
||||
|
||||
6. Apply only when every update address is named on the command line and the
|
||||
plan contains no create, delete, or replacement action.
|
||||
plan contains no create, delete, or replacement action. The dev direct ALB
|
||||
alias remains pinned during this phase and must not update.
|
||||
|
||||
The same reviewed change prepares the legacy dev CDK stack for ownership
|
||||
transfer. Before the Terraform apply, deploy `shoc-backend-deploy-dev` with
|
||||
`ManageGithubDeployRole=true` so both the role and generated inline-policy
|
||||
resource carry `Retain`. After Terraform succeeds and live verification passes,
|
||||
deploy the same reviewed SHA with `ManageGithubDeployRole=false`. This removes
|
||||
both resources from CloudFormation ownership without deleting them. Never use
|
||||
`ManageGithubDeployRole=true` again after that transfer.
|
||||
|
||||
The reviewed `adoption_complete=true` change updates ownership tags on IAM
|
||||
roles, instance profiles, and app-config secrets, and narrows the dev role to
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ module "environment" {
|
|||
aws_account_id = local.aws_account_id
|
||||
aws_region = local.aws_region
|
||||
environment = "dev"
|
||||
adoption_complete = false
|
||||
manage_eb_settings = false
|
||||
adoption_complete = true
|
||||
manage_eb_settings = true
|
||||
eb_application_name = local.eb_application_name
|
||||
eb_environment_name = local.eb_environment_name
|
||||
eb_environment_id = local.eb_environment_id
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue