|
| 1 | +--- |
| 2 | +name: Cloudformation stack-set & stack-set-instances |
| 3 | +on: |
| 4 | + workflow_call: |
| 5 | + inputs: |
| 6 | + aws-region: |
| 7 | + description: 'Aws region (in this region stackset enabled)' |
| 8 | + required: false |
| 9 | + default: 'us-east-2' |
| 10 | + type: string |
| 11 | + stackset-instance-region: |
| 12 | + description: 'Stackset-instance regions where you need cloudformation stacks' |
| 13 | + required: false |
| 14 | + default: 'us-east-2' |
| 15 | + type: string |
| 16 | + stack-set-name: |
| 17 | + description: 'Stack-set name defined here' |
| 18 | + required: true |
| 19 | + type: string |
| 20 | + template-url: |
| 21 | + description: 'Cloudformation template path add here (S3 Object URL)' |
| 22 | + required: true |
| 23 | + type: string |
| 24 | + OrganizationalUnitIds: |
| 25 | + description: 'Organization unit ID for deployment in target accounts when service_managed permission added' |
| 26 | + required: false |
| 27 | + type: string |
| 28 | + account-ids: |
| 29 | + description: 'account ids for self_managed permission added' |
| 30 | + required: false |
| 31 | + type: string |
| 32 | + parameter-overrides: |
| 33 | + description: 'The parameters to override in the stack inputs. You can pass a comma-delimited list or a file URL. The comma-delimited list has each entry formatted as <ParameterName>=<ParameterValue> or <ParameterName>="<ParameterValue>,<ParameterValue>".' |
| 34 | + required: false |
| 35 | + type: string |
| 36 | + permission-model: |
| 37 | + description: 'IAM role permission SERVICE_MANAGED/SELF_MANAGED choose one' |
| 38 | + required: false |
| 39 | + type: string |
| 40 | + auto-deployment-enabled: |
| 41 | + description: 'true or false (true when Service_managed policy enable else false for Self_managed)' |
| 42 | + required: true |
| 43 | + type: string |
| 44 | + RetainStacksOnAccountRemoval: |
| 45 | + description: 'true or false (true when Service_managed policy enable else false for Self_managed)' |
| 46 | + required: true |
| 47 | + type: string |
| 48 | + administration-role-arn: |
| 49 | + description: 'Administrator role arn add here for trust relation on admin and child account' |
| 50 | + required: false |
| 51 | + type: string |
| 52 | + execution-role-name: |
| 53 | + description: 'execution-role-name add here for trust relation in child account' |
| 54 | + required: false |
| 55 | + type: string |
| 56 | + secrets: |
| 57 | + AWS_ACCESS_KEY_ID: |
| 58 | + required: false |
| 59 | + description: 'AWS Access Key ID to install AWS CLI.' |
| 60 | + AWS_SECRET_ACCESS_KEY: |
| 61 | + required: false |
| 62 | + description: 'AWS Secret access key to install AWS CLI' |
| 63 | + AWS_SESSION_TOKEN: |
| 64 | + required: false |
| 65 | + description: 'AWS Session Token to install AWS CLI' |
| 66 | + AWS_ROLE_TO_ASSUME: |
| 67 | + required: false |
| 68 | + description: 'AWS Role ARN defined' |
| 69 | + GITHUB: |
| 70 | + required: false |
| 71 | + description: 'GitHub token' |
| 72 | + |
| 73 | +jobs: |
| 74 | + deploy-cf-stackset: |
| 75 | + runs-on: ubuntu-latest |
| 76 | + steps: |
| 77 | + - name: Checkout code from master branch |
| 78 | + uses: actions/checkout@v4 |
| 79 | + |
| 80 | + - name: Configure AWS Credentials |
| 81 | + uses: aws-actions/configure-aws-credentials@v4 |
| 82 | + with: |
| 83 | + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID}} |
| 84 | + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} |
| 85 | + aws-session-token: ${{ secrets.AWS_SESSION_TOKEN }} |
| 86 | + aws-region: ${{ inputs.aws-region }} |
| 87 | + role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }} |
| 88 | + |
| 89 | + - name: Check if StackSet exists or not-exist then create/update stack-set |
| 90 | + id: check-stackset |
| 91 | + run: | |
| 92 | + set +e |
| 93 | + result=$(aws cloudformation describe-stack-set --stack-set-name "${{ inputs.stack-set-name }}" 2>&1) |
| 94 | + RC=$? |
| 95 | + set -e |
| 96 | + if [ "${{ inputs.permission-model }}" = "SERVICE_MANAGED" ]; then |
| 97 | + if [ $RC -eq 0 ]; then |
| 98 | + echo "StackSet exists, updating..." |
| 99 | + aws cloudformation update-stack-set \ |
| 100 | + --stack-set-name ${{ inputs.stack-set-name }} \ |
| 101 | + --template-url ${{ inputs.template-url }} \ |
| 102 | + --parameters ${{ inputs.parameter-overrides }} \ |
| 103 | + --capabilities CAPABILITY_NAMED_IAM \ |
| 104 | + --permission-model ${{ inputs.permission-model }} \ |
| 105 | + --auto-deployment Enabled=${{ inputs.auto-deployment-enabled }},RetainStacksOnAccountRemoval=${{ inputs.RetainStacksOnAccountRemoval }} |
| 106 | + elif [ $RC -eq 254 ]; then |
| 107 | + if echo "$result" | grep -q "StackSetNotFoundException"; then |
| 108 | + echo "StackSet does not exist, creating..." |
| 109 | + aws cloudformation create-stack-set \ |
| 110 | + --stack-set-name ${{ inputs.stack-set-name }} \ |
| 111 | + --template-url ${{ inputs.template-url }} \ |
| 112 | + --parameters ${{ inputs.parameter-overrides }} \ |
| 113 | + --capabilities CAPABILITY_NAMED_IAM \ |
| 114 | + --permission-model ${{ inputs.permission-model }} \ |
| 115 | + --auto-deployment Enabled=${{ inputs.auto-deployment-enabled }},RetainStacksOnAccountRemoval=${{ inputs.RetainStacksOnAccountRemoval }} |
| 116 | + else |
| 117 | + exit $RC |
| 118 | + fi |
| 119 | + else |
| 120 | + exit $RC |
| 121 | + fi |
| 122 | + else |
| 123 | + if [ $RC -eq 0 ]; then |
| 124 | + echo "StackSet exists, updating..." |
| 125 | + aws cloudformation update-stack-set \ |
| 126 | + --stack-set-name ${{ inputs.stack-set-name }} \ |
| 127 | + --template-url ${{ inputs.template-url }} \ |
| 128 | + --capabilities CAPABILITY_NAMED_IAM \ |
| 129 | + --parameters ${{ inputs.parameter-overrides }} \ |
| 130 | + --administration-role-arn ${{ inputs.administration-role-arn }} |
| 131 | + elif [ $RC -eq 254 ]; then |
| 132 | + if echo "$result" | grep -q "StackSetNotFoundException"; then |
| 133 | + echo "StackSet does not exist, creating..." |
| 134 | + aws cloudformation create-stack-set \ |
| 135 | + --stack-set-name ${{ inputs.stack-set-name }} \ |
| 136 | + --template-url ${{ inputs.template-url }} \ |
| 137 | + --capabilities CAPABILITY_NAMED_IAM \ |
| 138 | + --parameters ${{ inputs.parameter-overrides }} \ |
| 139 | + --administration-role-arn ${{ inputs.administration-role-arn }} \ |
| 140 | + --execution-role-name AWSControlTowerExecution |
| 141 | + else |
| 142 | + exit $RC |
| 143 | + fi |
| 144 | + else |
| 145 | + exit $RC |
| 146 | + fi |
| 147 | + sleep 50s |
| 148 | + fi |
| 149 | +
|
| 150 | + - name: Create or Update StackSet-instance |
| 151 | + run: | |
| 152 | + stack_instance_list=$(aws cloudformation list-stack-instances --region ${{ inputs.stackset-instance-region }} --stack-set-name ${{ inputs.stack-set-name }}) |
| 153 | + if [ "${{ inputs.permission-model }}" == "SERVICE_MANAGED" ]; then |
| 154 | + if [[ "$stack_instance_list" == *'"Summaries": []'* ]]; then |
| 155 | + echo "StackSet-instance, creating..." |
| 156 | + aws cloudformation create-stack-instances \ |
| 157 | + --stack-set-name ${{ inputs.stack-set-name }} \ |
| 158 | + --deployment-targets OrganizationalUnitIds='["${{ inputs.OrganizationalUnitIds }}"]' \ |
| 159 | + --parameter-overrides ${{ inputs.parameter-overrides }} \ |
| 160 | + --regions ${{ inputs.stackset-instance-region }} |
| 161 | + else |
| 162 | + echo "StackSet-instance, updating..." |
| 163 | + aws cloudformation update-stack-instances \ |
| 164 | + --stack-set-name ${{ inputs.stack-set-name }} \ |
| 165 | + --deployment-targets OrganizationalUnitIds='["${{ inputs.OrganizationalUnitIds }}"]' \ |
| 166 | + --parameter-overrides ${{ inputs.parameter-overrides }} \ |
| 167 | + --regions ${{ inputs.stackset-instance-region }} |
| 168 | + fi |
| 169 | + else |
| 170 | + if [[ "$stack_instance_list" == *'"Summaries": []'* ]]; then |
| 171 | + echo "StackSet-instance, creating..." |
| 172 | + aws cloudformation create-stack-instances \ |
| 173 | + --stack-set-name ${{ inputs.stack-set-name }} \ |
| 174 | + --parameter-overrides ${{ inputs.parameter-overrides }} \ |
| 175 | + --accounts ${{ inputs.account-ids }} \ |
| 176 | + --regions ${{ inputs.stackset-instance-region }} \ |
| 177 | + --operation-preferences FailureToleranceCount=1,MaxConcurrentCount=2 |
| 178 | + else |
| 179 | + echo "StackSet-instance, updating..." |
| 180 | + aws cloudformation update-stack-instances \ |
| 181 | + --stack-set-name ${{ inputs.stack-set-name }} \ |
| 182 | + --parameter-overrides ${{ inputs.parameter-overrides }} \ |
| 183 | + --accounts ${{ inputs.account-ids }} \ |
| 184 | + --regions ${{ inputs.stackset-instance-region }} \ |
| 185 | + --operation-preferences MaxConcurrentPercentage=1 |
| 186 | + fi |
| 187 | + fi |
| 188 | +... |
0 commit comments